package com.xyx.www;

public class Test0724 {

	public static void main(String[] args) {
		/*
		 * test01(); System.out.println("====================="); test02();
		 * System.out.println("====================="); test03();
		 */
		// 调用String测试方法
		// stringDemo();
		stringTest();
		stringBuilder();

	}
	private static void stringBuilder() {
		StringBuilder sb=new StringBuilder("小飞");
		System.out.println(sb);
		sb.append("好帅");
		System.out.println();
	
	}

	private static void stringTest() {
		// 变量1
		String str00 = new String("小明"); // 执行到此行，创建了2个对象 1个在字符串常量池中，1个在堆内存中
		String str01 = new String("小明"); // 执行到此行，创建了3个对象 1个在字符串常量池中，2个在堆内存中
		String str02 = "小明"; // 字符串常量// 执行到此行，创建了3个对象 1个在字符串常量池中，2个在堆内存中
		String str03 = "小明";// 执行到此行，执行到此行，创建了3个对象 1个在字符串常量池中，2个在堆内存中
		String str041 = "小";
		String str04 = str041 + "明"; // 执行到此，创建了6个对象 3个在字符串常量池中，3个在堆内存中
		// 如果两个纯粹字符创常量直接相加，则还是字符串常量，初次以外其他情况则需要开辟堆内存；
		// String str04 = "小" + "明";

		// str01新创建内存地址
		System.out.println("str00 == str01:" + (str00 == str01)); // false
		// 两个地址值相等
		System.out.println("str00.equals(str01):" + (str00.equals(str01)));// true
		//str02在常量池中，str00在堆中
//		System.out.println("str00 == str02:" + (str00 == str02)); // false
		//两个地址中的值相等
		System.out.println("str00.equals(str02):" + (str00.equals(str02)));// true
		//在常量池中存在相等值的对象，直接引用
		System.out.println("str02 == str03:" + (str02 == str03)); // true
		//两个地址中的值相等
		System.out.println("str02.equals(str03):" + (str02.equals(str03)));// true
		//str04用+号把变量把041和常量相加会创建新的内存地址，因为引用了新地址相加
		System.out.println("str04 == str00:" + (str04 == str00)); // false
		//两个地址中的值相等
		System.out.println("str04.equals(str00):" + (str04.equals(str00)));// true
		//str04用+号把变量把041和常量相加会创建新的内存地址，因为引用了新地址相加
		System.out.println("str04 == str02:" + (str04 == str02)); // false
		//两个地址中的值相
		System.out.println("str04.equals(str02):" + (str04.equals(str02)));// true
	}

	private static void stringDemo() {
		// 定义字符串
		String str1 = "qwerasdzxc";
		System.out.println(str1.charAt(0));
		for (int i = 0; i < str1.length(); i++) {
			System.out.print(" " + str1.charAt(i));
		}

	}

	/**
	 * 冒泡排序测试类
	 */
	private static void test01() {
		int[] arr = { 1, 2, 8, 3, 4, 6, 9, 7 };
		System.out.println("排序之前的数组：");
		printArr(arr);
		bubbleSort(arr);
		System.out.println("排序之后的数组");
		printArr(arr);
	}

	/**
	 * 优化每轮中比较次数的测试类
	 */
	private static void test02() {
		int[] arr = { 1, 2, 8, 3, 4, 6, 9, 7 };
		System.out.println("排序之前的数组：");
		printArr(arr);
		bubbleSort2(arr);
		System.out.println("排序之后的数组");
		printArr(arr);
	}

	/**
	 * 优化比较轮数的测试类
	 */
	private static void test03() {
		int[] arr = { 1, 2, 8, 3, 4, 6, 9, 7 };
		System.out.println("排序之前的数组：");
		printArr(arr);
		bubbleSort3(arr);
		System.out.println("排序之后的数组");
		printArr(arr);
	}

	/**
	 * 冒泡排序算法【从小到大】
	 * 
	 * @param arr
	 *            被排序数组【方法定义为了void，因为数组是按引用传参】
	 */
	private static void bubbleSort(int[] arr) {
		// 统计比较次数
		int count = 0;
		// 外层for循环，控制冒泡排序算法的轮数
		for (int i = 0; i < arr.length - 1; i++) {
			// 内存for循环，控制每一轮中的两两比较次数
			for (int j = 0; j < arr.length - 1; j++) {
				// 按照排序要求进行比较，并交换相邻两个元素
				if (arr[j] > arr[j + 1]) {
					// 比较交换
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
				// 经过一次比较，计数器+1
				count++;
			}
		}
		System.out.println("本次排序比较次数：" + count);
	}

	/**
	 * 冒泡排序算法【从小到大】 -- 优化每轮中的比较次数
	 * 
	 * @param arr
	 *            被排序数组【方法定义为了void，因为数组是按引用传参】
	 */
	private static void bubbleSort2(int[] arr) {
		// 统计比较次数
		int count = 0;
		// 外层for循环，控制冒泡排序算法的轮数
		for (int i = 0; i < arr.length - 1; i++) {
			// 内存for循环，控制每一轮中的两两比较次数
			// arr.length - i - 1 优化每轮比较的次数
			for (int j = 0; j < arr.length - i - 1; j++) {
				// 按照排序要求进行比较，并交换相邻两个元素
				if (arr[j] > arr[j + 1]) {
					// 比较交换
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
				}
				// 经过一次比较，计数器+1
				count++;
			}
		}
		System.out.println("本次排序比较次数：" + count);
	}

	/**
	 * 冒泡排序算法【从小到大】 -- 优化比较轮数
	 * 
	 * @param arr
	 *            被排序数组【方法定义为了void，因为数组是按引用传参】
	 */
	private static void bubbleSort3(int[] arr) {
		// 统计比较次数
		int count = 0;
		// 外层for循环，控制冒泡排序算法的轮数
		for (int i = 0; i < arr.length - 1; i++) {
			// 每轮是否发生交换变量：默认没有发生交换
			boolean isChanged = false;
			// 内存for循环，控制每一轮中的两两比较次数
			// arr.length - i - 1 优化每轮比较的次数
			for (int j = 0; j < arr.length - i - 1; j++) {
				// 按照排序要求进行比较，并交换相邻两个元素
				if (arr[j] > arr[j + 1]) {
					// 比较交换
					int temp = arr[j];
					arr[j] = arr[j + 1];
					arr[j + 1] = temp;
					// 当前本轮比较中，发生了交换，修改标志变量
					isChanged = true;
				}
				// 经过一次比较，计数器+1
				count++;
			}
			// 如果当前轮没有发生交换，则无需在进行下一轮比较，可以终止比较轮数的循环【终止外层循环】
			// if (!isChanged) {
			if (isChanged == false) {
				// 没有发生交互，终止外层循环
				break;
			}
		}
		System.out.println("本次排序比较次数：" + count);
	}

	/**
	 * 打印数组
	 * 
	 * @param arr
	 *            被打印的数组
	 */
	private static void printArr(int[] arr) {
		for (int i : arr) {
			System.out.print(" " + i);
		}
		System.out.println();
	}
}
